<!--
Date: 2025-08-13
Copyright (c) 2025 Industrial Software Feature Database
-->
<template>
  <div class="business-map__source" style="width: 100%; overflow: auto; height: calc(100vh - 200px); position: relative">
    <div ref="chartRef" :style="{ height: containerHeight + 'px' }" />
  </div>
  <el-dialog title="字段详情" width="1200" v-model="tableFiledVisible" @close="tableFiledVisible = false">
    <el-table v-loading="loading" :data="metaList" style="width: 100%" border>
      <el-table-column label="字段名称" align="center" prop="fieldName" fixed="left" show-overflow-tooltip />
      <el-table-column label="字段中文名" align="center" prop="fieldChineseName" show-overflow-tooltip />
      <el-table-column label="数据类型" align="center" prop="fieldType" show-overflow-tooltip />
      <el-table-column label="默认值" align="center" prop="defaultValue" show-overflow-tooltip
        ><template #default="scope">
          {{ scope.row.defaultValue || '-' }}
        </template>
      </el-table-column>
      <el-table-column label="是否允许为空" align="center" prop="isNullable" show-overflow-tooltip>
        <template #default="scope">
          {{ scope.row.isNullable == 1 ? '是' : '否' || '-' }}
        </template>
      </el-table-column>
      <el-table-column label="是否唯一" align="center" prop="isUnique" show-overflow-tooltip>
        <template #default="scope">
          {{ scope.row.isUnique || '-' }}
        </template>
      </el-table-column>
      <el-table-column label="说明及备注" align="center" prop="fieldDescription" show-overflow-tooltip>
        <template #default="scope">
          {{ scope.row.fieldDescription || '-' }}
        </template>
      </el-table-column>
    </el-table>
  </el-dialog>
  <el-dialog title="数据详情" width="1200" v-model="apiLoadVisible" @close="apiLoadVisible = false">
    <template v-if="dataAssetType == 'tree' && apiLoadVisible">
      <MaterialDetail
        ref="materialDetailRef"
        :treeData="detailTreeData"
        :canEdit="false"
      />
    </template>
    <template v-else-if="dataAssetType == 'table' && apiLoadVisible">
      <el-table :data="assetTableData" border>
        <el-table-column v-for="td in filterTableColumns(assetTableData[0])" :key="td._index" :label="td.chinese + '(' + td.field + ')'" :prop="td.field" min-width="150" show-overflow-tooltip>
          <template #default="scope">
            <el-input v-if="pageType == 'EDIT' || pageType == 'ADD'" v-model="scope.row[td._index]['data']"></el-input>
            <span v-else>{{ scope.row[td._index]['data'] || '' }}</span>
          </template>
        </el-table-column>
      </el-table>
      <div class="pagenation">
        <el-pagination
          v-show="total > 0"
          layout="prev, pager, next,jumper"
          v-model:page="tableParams.pageNum"
          v-model:limit="tableParams.pageSize"
          :total="total"
          @current-change="handleCurrentChange"
        />
      </div>
    </template>
  </el-dialog>
  <el-dialog ref="formDialogRef" v-model="userVisible" title="用户详情" width="600px" append-to-body @close="userVisible = false">
    <el-form ref="userFormRef" :model="form" label-width="80px">
      <el-row>
        <el-col :span="12">
          <el-form-item label="用户昵称" prop="nickName">
            <span>{{ form.nickName }}</span>
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="手机号码" prop="phonenumber">
            <span>{{ form.phonenumber }}</span>
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="邮箱" prop="email">
            <span>{{ form.email }}</span>
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="用户名称" prop="userName">
            <span>{{ form.userName }}</span>
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="用户性别">
            <span>{{ sexMap[form.sex] }}</span>
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="状态">
            <span>{{ statusMap[form.status] }}</span>
          </el-form-item>
        </el-col>
        <el-col :span="24">
          <el-form-item label="备注">
            <span>{{ form.remark }}</span>
          </el-form-item>
        </el-col>
      </el-row>
    </el-form>
  </el-dialog>
</template>
<script setup name="BusinessMapSource">
import * as echarts from 'echarts';
import api from '@/api/system/user';
import MaterialDetail from '@/views/material/component/MaterialDetail.vue';
import { getBusinessMapRelationShip } from '@/api/businessMap/index';
import {getModelDetail } from '@/api/metaData/model.ts';
import { getAssetDataList } from '@/api/material/index.ts';
import { dataServicesHistoryDataList } from '@/api/dataServices/index.ts';
import { downloadDataImportFile } from '@/api/dataAcquisition';
import { downloadFile } from '@/utils/index';
const sexMap = {
  '0': '男',
  '1': '女',
  '2': '未知'
}
const statusMap = {
  '0': '正常',
  '1': '停用'
}
const props = defineProps(['sourceId']);
const chartRef = ref();
let chartInstance = null;
const containerHeight = ref(400) // 初始默认高度
const sourceData = ref(null);
const metaList = ref([]);
const tableFiledVisible = ref(false);
const apiLoadVisible = ref(false)
const detailTreeData = ref(null);
const dataAssetType = ref('');
const assetTableData = ref([]);
const total = ref(0);
const currentModelId = ref('');
const currentRecordId = ref('');
const userVisible = ref(false);
const tableParams = ref({
  pageNum: 1, 
  pageSize: 10,
})
const form = ref({
  userId: undefined,
  deptId: undefined,
  userName: '',
  nickName: undefined,
  password: '',
  phonenumber: undefined,
  email: undefined,
  sex: undefined,
  status: '0',
  remark: '',
  postIds: [],
  roleIds: []
});
// 浅色主题节点样式配置
// 黑白主题节点配置
const nodeStyles = {
  start: {
    symbol: 'circle',
    color: '#FFFFFF',    // 白色背景
    borderColor: '#000' // 黑色边框
  },
  process: {
    symbol: 'rect',
    color: '#F0FFF0',  // 流程节点：蜜露白
    borderColor: '#000'
  },
  decision: {
    symbol: 'diamond',
    color: '#FFFFFF',
    borderColor: '#000'
  },
  end: {
    symbol: 'roundRect',
    color: '#FFFFFF',
    borderColor: '#000'
  }
}
const filterTableColumns = (cols) => {
  cols.forEach((item, index) => {
    item._index = index;
  })
  return cols.filter(col => col?.type !== 'info');
}
const handleCurrentChange = (num) => {
  tableParams.value.pageNum = num;
  getAssetDataDetail(currentModelId.value, currentRecordId.value);
};
// 计算树的高度
const calculateTreeHeight = (data) => {
  let maxDepth = 0
  const nodeSpacing = 80 // 节点垂直间距
  const nodeHeight = 50 // 单个节点高度

  const traverse = (node, depth) => {
    maxDepth = Math.max(maxDepth, depth)
    let addH = node.children?.length || 0;
    node.children?.forEach(child => traverse(child, depth + addH))
  }

  traverse(data, data.children?.length || 1)
  console.log('maxDepth', maxDepth)
  return maxDepth * (nodeHeight + nodeSpacing) + 100 // 增加边距
}
const initChart = () => {
  chartInstance = echarts.init(chartRef.value)
  
  const option = {
    backgroundColor: '#fff',
    tooltip: {
      trigger: 'item',
      formatter: ({ data }) => data.name,
      backgroundColor: '#fff',
      borderColor: '#000',
      textStyle: {
        color: '#000'
      }
    },
    series: [{
      type: 'tree',
      expandAndCollapse: false, // 关闭展开收起交互
      data: [sourceData.value],
      // layout: 'horizontal',
      orient: 'LR',
      initialTreeDepth: -1,
      lineStyle: {
        color: '#000',
        width: 1.5,
        type: 'solid',    // 线型改为实线
        curveness: 0      // 完全消除曲线
      },
      edgeShape: 'polyline', // 设置为折线模式
      edgeForkPosition: '50%', // 折线转折点位置
      layout: 'orthogonal',  // 正交布局模式
      symbol: 'rect', //(value, params) => nodeStyles[params.data.type]?.symbol || 'rect',
      symbolSize: [260, 70],
      itemStyle: {
        color: {
          type: 'linear',
            x: 0,
            y: 0,
            x2: 1,
            y2: 1,
            colorStops: [{
              offset: 0, color: '#F0FFF0' // 浅绿色
            }, {
              offset: 1, color: '#E0FFFF' // 浅蓝色
            }]
        },
        // borderColor: '#E0FFFF',
        // borderWidth: 1,
        // borderRadius: 0,
        // shadowBlur: 0 // 移除阴影
          normal: {
              borderWidth: 0, // 设置边框宽度
              borderColor: '#ccc', // 设置边框颜色
              color: '#fff', // 设置节点背景色，如果不设置，则使用默认颜色
              // shadowBlur: 1, // 设置阴影模糊度，增加立体感
              // shadowColor: 'rgba(0, 0, 0, 0.5)', // 设置阴影颜色
              // shadowOffsetX: 1, // 设置阴影水平偏移
              // shadowOffsetY: 1 // 设置阴影垂直偏移
          },
          emphasis: { // 高亮状态的样式设置
              // borderWidth: 1, // 高亮时边框宽度可以加大，突出显示效果
              // borderColor: '#444' // 高亮时边框颜色变化，增强视觉效果
          }
      },
      label: {
        position: 'inside',
        color: '#000', // 黑色字体
        fontSize: 14,
        fontWeight: 'normal',
        formatter: ({ data }) => {
          // if (data.level == 1) {
          //   return `${data.databaseName}`;
          // } else if (data.level == 2) {
          //   return `${data.modelName}(${data.versionNumber})`
          // } else if (data.level == 3) {
          //   return `${data.importUserName}、${data.dataImportTime}、${data.inventoryCount}`
          // } else if (data.level == 4) {
          //   return ` ${data.fileName ? data.fileName.replace(/(.{25})/g, '$1\n') : '空'}`
          // }
          return renderNodeContent(data)
        },
        rich: { // 富文本样式设置
          a: { // 自定义样式名称
            color: '#000', // 字体颜色
            width: 260, // 宽度
            height: 35, // 高度
            fontSize: 14, // 字体大小
            fontWeight: '600', // 字体粗细
            borderWidth: 1,
            borderColor: '#ccc', // 边框
            padding: [2, 4], // 内边距 
         },
         b: { // 自定义样式名称
          color: '#000', // 字体颜色
            width: 260, // 宽度
            height: 35, // 高度
            fontSize: 14, // 字体大小
            // fontWeight: '', // 字体粗细
            borderWidth: 1,
            borderColor: '#ccc', // 边框
            padding: [2, 4], // 内边距 
          },
          c: {
            color: '#000', // 字体颜色
            width: 180, // 宽度
            height: 35, // 高度
            fontSize: 14, // 字体大小
            fontWeight: 'bold', // 字体粗细
            borderWidth: 1,
            borderColor: '#ccc', // 边框
            padding: [2, 4], // 内边距 
          },
          d: {
            color: '#000', // 字体颜色
            width: 80, // 宽度
            height: 35, // 高度
            fontSize: 14, // 字体大小
            fontWeight: 'bold', // 字体粗细
            borderWidth: 1,
            borderColor: '#ccc', // 边框
            padding: [2, 4], // 内边距 
          },
          m: {
            color: '#409EFF', // 字体颜色
            width: 80, // 宽度
            height: 35, // 高度
            fontSize: 14, // 字体大小
            fontWeight: 'bold', // 字体粗细
            borderWidth: 1,
            borderColor: '#ccc', // 边框
            padding: [2, 4], // 内边距 
          },
          e: {
            color: '#000', // 字体颜色
            width: 180, // 宽度
            height: 35, // 高度
            fontSize: 14, // 字体大小
            // fontWeight: 'bold', // 字体粗细
            borderWidth: 1,
            borderColor: '#ccc', // 边框
            padding: [2, 4], // 内边距 
          },
          f: {
            color: '#000', // 字体颜色
            width: 80, // 宽度
            height: 35, // 高度
            fontSize: 14, // 字体大小
            // fontWeight: 'bold', // 字体粗细
            borderWidth: 1,
            borderColor: '#ccc', // 边框
            padding: [2, 4], // 内边距 
          },
          g: {
            color: '#000', // 字体颜色
            width: 80, // 宽度
            height: 35, // 高度
            fontSize: 14, // 字体大小
            fontWeight: 'bold', // 字体粗细
            borderWidth: 1,
            borderColor: '#ccc', // 边框
            padding: [2, 4], // 内边距 
          },
          h: {
            color: '#000', // 字体颜色
            width: 80, // 宽度
            height: 35, // 高度
            fontSize: 14, // 字体大小
            fontWeight: 'bold', // 字体粗细
            borderWidth: 1,
            borderColor: '#ccc', // 边框
            padding: [2, 4], // 内边距 
          },
          i: {
            color: '#000', // 字体颜色
            width: 80, // 宽度
            height: 35, // 高度
            fontSize: 14, // 字体大小
            // fontWeight: 'bold', // 字体粗细
            borderWidth: 1,
            borderColor: '#ccc', // 边框
            padding: [2, 4], // 内边距 
          },
          j: {
            color: '#409EFF', // 字体颜色
            width: 80, // 宽度
            height: 35, // 高度
            fontSize: 14, // 字体大小
            // fontWeight: '', // 字体粗细
            borderWidth: 1,
            borderColor: '#ccc', // 边框
            padding: [2, 4], // 内边距 
            overflow: 'hidden', // 隐藏超出部分
            textOverflow: 'ellipsis', // 显示省略号
            whiteSpace: 'nowrap', // 不换行
          },
        },
      },
      lineStyle: {
        color: '#ccc', // 黑色连接线
        width: 1.5,
        curveness: 0
      },
      emphasis: {
        disabled: true // 完全禁用hover效果
      }
    }]
  }

  chartInstance.setOption(option)
  window.addEventListener('resize', handleResize)
  // 监听节点点击事件
  chartInstance.on('click', async function (params) {
      // params 包含了点击节点的相关信息
      // console.log('点击的节点名称: ', params);
      // console.log('点击的节点数据: ', params.data);
      params.data.collapsed = !params.data.collapsed;
      // 可以在这里添加自定义的逻辑，例如弹出提示框、跳转到其他页面等
      if (params.data.level == 4) {
        // if (params.data.importMethod === 'API导入') {
        //   dataServicesHistoryDataList({id: params.data.id, pageSize: 9999, pageNum: 1}).then(res => {
        //     detailTreeData.value = res.data.record;
        //     apiLoadVisible.value = true;
        //   })
          
        // } else {
        //   params.data.fileUrl && window.open('http://172.16.41.118/file'+params.data.fileUrl, '_blank')          
        // }
        detailTreeData.value = [];
        assetTableData.value = [];
        // getAssetDataList({modelId: params.data.modelId, importRecordIds: [params.data.recordId], pageNum: tableParams.value.pageNum,
        //   pageSize: tableParams.value.pageSize}).then(res => {
        //   dataAssetType.value = res.data.showType;
        //   if (res.data.showType == 'tree') {
        //     detailTreeData.value = res.data?.treeResult;
        //   } else if (res.data.showType == 'table') {
        //     assetTableData.value = res.data?.tableResult?.contentData || [];
        //     total.value = res.data?.tableResult?.totalSize || 0;
        //   }
        //   apiLoadVisible.value = true;
        // })
        currentModelId.value = params.data.modelId;
        currentRecordId.value = params.data.recordId;
        const methodArr = ['Json导入', 'XML导入', 'EXCEL导入', '压缩包导入']
        if (methodArr.includes(params.data.importMethod)) {
          const suffix = params.data.fileName.split('.')[1];
          const fileName = params.data.fileName.split('.')[0];

          downloadDataImportFile({recordId: currentRecordId.value}).then(res => {
            downloadFile(res, `${fileName}`, suffix);
          })
        } else {
          getAssetDataDetail(params.data.modelId, params.data.recordId);
        }
      } else if (params.data.level == 2 && params.data.modelId) {
        getFieldList(params.data.modelId)
      } else if (params.data.level == 3 && params.data.importUserId) {
        const { data } = await api.getUser(params.data.importUserId);
        form.value = data.user;
        userVisible.value = true;
      } 
  });
}

const getAssetDataDetail = (modelId, recordId) => {
  getAssetDataList({modelId: modelId, importRecordIds: [recordId], pageNum: tableParams.value.pageNum,
    pageSize: tableParams.value.pageSize}).then(res => {
    dataAssetType.value = res.data.showType;
    apiLoadVisible.value = true;
    if (res.data.showType == 'tree') {
      if (res?.data?.treeResult?.content?.length > 0) {
        res?.data?.treeResult?.content.forEach(item => {
          item.hasChildren = res?.data?.treeResult?.hasChildren;
        })
      }  
      nextTick(() => {
        detailTreeData.value = res.data?.treeResult.content;
      })
    } else if (res.data.showType == 'table') {
      assetTableData.value = res.data?.tableResult?.contentData || [];
      total.value = res.data?.tableResult?.totalSize || 0;
    }
    
  })
}

const renderNodeContent = (node) => {
  if (node.level == 1) {
    return `{a|要素库类型}\n{b|${node.databaseName}}`;   
  } else if (node.level == 2) {
    return `{c|模型名称}{d|版本号}\n{e|${node.modelName}}{f|${node.versionNumber}}`;   //`${node.modelName}(${node.versionNumber})`;     
  } else if (node.level == 3) {
    return `{d|操作人}{c|导入时间}\n{m|${node.importUserName}}{e|${node.dataImportTime}}`;
    // return `${node.importUserName}、${node.dataImportTime}`; 
  } else if (node.level == 4) {
    return `{g|导入方式}{g|数量}{h|内容}\n{i|${node.importMethod}}{i|${node.inventoryCount}}{j|原始数据查看}`;
    // return  node.importMethod === 'API导入' ? `【API导入】，${node.inventoryCount}` : `【${node.importMethod}】${node.fileName? node.fileName.replace(/(.{25})/g, '$1\n') + '，' + node.inventoryCount : '空'}`
  }
}

const getFieldList = (id) => {
  metaList.value = [];
  getModelDetail({id}).then(res => {
    metaList.value = res.data.fieldList;
    tableFiledVisible.value = true;
  })
}

// 保持窗口自适应逻辑不变
const handleResize = () => chartInstance?.resize()
onMounted(() => {
  getBusinessMapRelationShip({sceneMapStepModelRefId: props.sourceId}).then(res => {
    if (res.data) {
      sourceData.value = res.data;
      containerHeight.value = calculateTreeHeight(res.data)
      nextTick(() => {
        initChart();
      })
    }
  })
})
onBeforeUnmount(() => {
  window.removeEventListener('resize', handleResize)
  chartInstance?.dispose()
})
</script>
<style lang="less" scoped>

</style>
